package org.example.idempotent;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;

/**
 * Redis Lua脚本缓存工具类：项目启动时预加载脚本，避免高并发时重复读取文件
 */
@Component
public class RedisScriptCache {
    private static final Logger log = LoggerFactory.getLogger(RedisScriptCache.class);

    // 缓存Lua脚本内容（静态变量确保全局唯一）
    private static String idempotentMqScriptContent;
    // 缓存RedisScript对象（避免重复创建）
    private static RedisScript<String> idempotentMqRedisScript;

    /**
     * 项目启动时执行：加载Lua脚本并缓存
     */
    @PostConstruct
    public void init() {
        try {
            // 读取脚本文件（路径：src/main/resources/lua/idempotent_mq_script.lua）
            ClassPathResource resource = new ClassPathResource("lua/idempotent_mq_script.lua");
            byte[] scriptBytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
            idempotentMqScriptContent = new String(scriptBytes, StandardCharsets.UTF_8);
            
            // 创建并缓存RedisScript对象
            idempotentMqRedisScript = new DefaultRedisScript<>(idempotentMqScriptContent, String.class);
            log.info("Lua脚本预加载成功：idempotent_mq_script.lua");
        } catch (Exception e) {
            // 启动阶段失败直接抛异常，避免运行时才发现问题
            log.error("Lua脚本预加载失败，请检查文件是否存在或格式是否正确", e);
            throw new RuntimeException("初始化Redis脚本缓存失败", e);
        }
    }

    /**
     * 获取预加载的MQ幂等消费Lua脚本
     */
    public static RedisScript<String> getIdempotentMqScript() {
        if (idempotentMqRedisScript == null) {
            throw new IllegalStateException("Lua脚本尚未初始化，请检查是否在Spring环境中使用");
        }
        return idempotentMqRedisScript;
    }
}